/*******************************************************************************
GameKit.cpp

	Author:		LiuDingXi
	e-mail:		liudx@gmail.com
	Date time:	2009-08-17

	Copyright (C) 2009
	All rights reserved.
	
*******************************************************************************/
#include "StdAfx.h"
#include "GameKit.h"
#include "StringKit.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

////////////////////////////////////////////////////////////////////////////////

CGameKit::CGameKit()
{
}

CGameKit::~CGameKit()
{
	Free();
}

BOOL CGameKit::Load(CArchive& ar)
{
	TCHAR szFolder[MAX_PATH];
	 _tcscpy(szFolder, ar.GetFile()->GetFilePath());
	 LPTSTR pTail = PathFindFileName(szFolder);
	 if(pTail)
	 {
		LPCTSTR p = pTail;		 
		while(*p && *p != _T('.'))
		{
			m_szName += *p++;
		}

		 *pTail = 0;

	 }
	 m_szFolder = szFolder;

	 m_szStrFile.Empty();

	CString s;
	while(ar.ReadString(s))
	{
		if(s.IsEmpty())
			continue;
		
		LPCTSTR p = s;
		MoveToBegin(p);
		
		#define IS_TAG(tag)	_tcsnicmp(p, tag, _tcslen(tag)) == 0
		
		if(IS_TAG(_T("import")))
		{
			p += 6;

			if(strchr(p, '{') != NULL)
			{
				CString szName = ParseOf(p);

				SCENE* pScene = new SCENE;
				pScene->m_szName = szName;
				pScene->szFile = szName + ".scn";
				m_SceneList.push_back(pScene);

				if(!pScene->Load(szFolder, p))
				{
					printf("Scene %s Load Error\n", szName);
					return FALSE;
				}
				
			}
			else
			{
				CString szFile = ParseOf(p);
				
				TCHAR szFileName[MAX_PATH];
				_tcscpy(szFileName, szFolder);
				PathAppend(szFileName, szFile);
				
				if(PathFileExists(szFileName))
				{
					LPCTSTR pExt = PathFindExtension(szFileName);
					if(pExt)
					{
						if(_tcsicmp(pExt, _T(".scn")) == 0)
						{
							SCENE* pScene = new SCENE;
							pScene->szFile = szFile;
							m_SceneList.push_back(pScene);
							
							CFile file(szFileName, CFile::modeRead);
							CArchive arScene(&file, CArchive::load);
							if(!pScene->Load(arScene))
							{
								printf("Scene %s Load Error\n", pScene->m_szName);
								return FALSE;
							}
						}
						else if(_tcsicmp(pExt, _T(".str")) == 0)
						{
							m_szStrFile = szFileName;
						}
					}
				}
				else
				{
					return FALSE;
				}
			}
		}
		else if(IS_TAG(_T("name")))
		{
			p += 4;
			m_szName = ParseOf(p);
		}
	}	
	return TRUE;
}

BOOL CGameKit::Store(CArchive& ar)
{
	list<SCENE*>::iterator it;
	it = m_SceneList.begin();
	while(it != m_SceneList.end())
	{
		SCENE* pScene = *it++;
		CString szImport(_T("import\t"));
		szImport += pScene->szFile;
		szImport += _T("\r\n");
		ar.WriteString(szImport);
	}
	return TRUE;
}

BOOL CGameKit::Free()
{
	list<SCENE*>::iterator it;
	it = m_SceneList.begin();
	while(it != m_SceneList.end())
	{
		SCENE* pScene = *it++;
		delete pScene;
	}
	m_SceneList.clear();
	return TRUE;
}


BOOL CGameKit::Build(LPCTSTR szOutput)
{
	CCoder Coder;

	Coder.SetFolder(szOutput);

	if(!Coder.HasSrcFile(m_szName))
	{
		Coder.TemplateFor(_T("game"), _T("Game"), m_szName, m_szName);
	}

	if(1)
	{
		Coder.Load(m_szName + _T(".h"));

		CString szSceneHead;
		CString szSceneList;

		list<SCENE*>::iterator it;
		it = m_SceneList.begin();
		while(it != m_SceneList.end())
		{
			SCENE* pScene = *it++;

			CString szName = pScene->m_szName;

			CString szLine;
			szLine.Format(_T("\tC%s m_%s;\r\n"), szName, szName);
			CString szHead;
			szHead.Format(_T("#include \"%s.h\"\r\n"), szName);

			szSceneHead += szHead;
			szSceneList += szLine;
		}
		Coder.LnRemove(_T("SCENE_INCLUDE_BEGIN"), _T("SCENE_INCLUDE_END"));
		Coder.LnInsert(_T("SCENE_INCLUDE_BEGIN"), szSceneHead);

		Coder.LnRemove(_T("SCENE_LIST_BEGIN"), _T("SCENE_LIST_END"));
		Coder.LnInsert(_T("SCENE_LIST_BEGIN"), szSceneList);


		Coder.Save(m_szName + _T(".h"));
	}

	if(1)
	{
		list<SCENE*>::iterator it;
		it = m_SceneList.begin();
		while(it != m_SceneList.end())
		{
			SCENE* pScene = *it++;

			pScene->Build(szOutput);
		}
	}

	if(!m_szStrFile.IsEmpty())
	{
		try
		{
			CFile file(m_szStrFile, CFile::modeRead);
			CArchive ar(&file, CArchive::load);

			CStringKit skit;

			if(skit.Load(ar))
			{
				skit.SaveDat(szOutput);
			}

		}
		catch(CException* e)
		{
			e->ReportError();
			e->Delete();
		}
	}
	
	return TRUE;
}
